#ifndef KERNELLIST_H
#define KERNELLIST_H
/**********************************************************
功能: 计算MEMBER成员在TYPE结构体中的偏移量
**********************************************************/
#define offsetof(TYPE, MEMBER)  (unsigned long)(&(((TYPE*)0)->MEMBER))


/**********************************************************
功能: 计算链表元素的起始地址
输入:
    ptr：    type结构体中的链表指针
    type:   结构体类型
    member: 链表成员名称
**********************************************************/
#define container_of(ptr, type, member) (type *)((char*)(ptr) - offsetof(type, member))
typedef struct list_head
{
    struct list_head *prev,*next;
}ListCore;

/*
简单双链表实现。
一些内部函数（“__xxx”）时是非常有用的
操纵整个列表而不是单一条目
有时候，我们已经知道未来沪指条目，我们可以
生成更好的代码，而不是直接使用它们
使用通用的单输入例程。
 */

#define LIST_HEAD_INIT(name) { &(name), &(name) }

#define LIST_HEAD(name) \
    struct list_head name = LIST_HEAD_INIT(name)

static inline void INIT_LIST_HEAD(ListCore *list)
{
    list->next = list;
    list->prev = list;
}
/*
插入一个新项已知两个之间。
这仅适用于我们所知道的内部列表操作.
上一页/下一项目已！
 */
static inline void __list_add(ListCore *newList,
                  ListCore *prev,
                  ListCore *next)
{
    next->prev = newList;
    newList->next = next;
    newList->prev = prev;
    prev->next = newList;
}
/*


list_add -添加新条目
@newList：newList被添加
head：列表head添加它后
插入一个newList指定的head后。
这是很好的实现栈。
 */
static inline void list_add(ListCore *newList, ListCore *head)
{
    __list_add(newList, head, head->next);
}
/*
list_add_tail -添加一个新newList
@newList：添加newList
@head：列表head添加它之前
在指定头前插入新条目。
这是有用的实现队列。
 */
static inline void list_add_tail(ListCore *newList, ListCore *head)
{
    __list_add(newList, head->prev, head);
}
/*


删除一个列表项的Prev/Next条目指向对方。
这仅仅是内部列表操作，我们知道prev/next！
 */
static inline void __list_del(ListCore * prev, ListCore * next)
{
    next->prev = prev;
}
/*
list_del删除条目列表。
entry：从列表中删除的元素。
注：list_empty()入境不返回之后，进入未定义的状态。
 */
static inline void list_del(ListCore *entry)
{
    __list_del(entry->prev, entry->next);
    INIT_LIST_HEAD(entry);
}
/*
list_replace -取代旧的进入新的一个
@old：要被替换的元素
@newList：插入newList
如果@old空了，它将被覆盖。
 */
static inline void list_replace(ListCore *old,
                ListCore *newList)
{
    newList->next = old->next;
    newList->next->prev = newList;
    newList->prev = old->prev;
    newList->prev->next = newList;
}

static inline void list_replace_init(ListCore *old,
                    ListCore *newList)
{
    list_replace(old, newList);
    INIT_LIST_HEAD(old);
}

/*
list_move删除从一个列表并添加另一个的头
@list：移动的入口
@head：在我们进入之前的头
 */
static inline void list_move(ListCore *list, ListCore *head)
{
    list_del(list);
    list_add(list, head);
}
/*
  list_move_tail - delete from one list and add as another's tail
  @list: the entry to move
  @head: the head that will follow our entry
 */
static inline void list_move_tail(ListCore *list,
                  ListCore *head)
{
    list_del(list);
    list_add_tail(list, head);
}
/*
  list_is_last - tests whether @list is the last entry in list @head
  @list: the entry to test
  @head: the head of the list
 */
static inline int list_is_last(const ListCore *list,
                const ListCore *head)
{
    return list->next == head;
}
/*
  list_empty - tests whether a list is empty
  @head: the list to test.
 */
static inline int list_empty(const ListCore *head)
{
    return head->next == head;
}
/*
  list_empty_careful - tests whether a list is empty and not being modified
  @head: the list to test

  Description:
  tests whether a list is empty _and_ checks that no other CPU might be
  in the process of modifying either member (next or prev)

  NOTE: using list_empty_careful() without synchronization
  can only be safe if the only activity that can happen
  to the list entry is list_del_init(). Eg. it cannot be used
  if another CPU could re-list_add() it.
 */
static inline int list_empty_careful(const ListCore *head)
{
    ListCore *next = head->next;
    return (next == head) && (next == head->prev);
}

/*
  list_rotate_left - rotate the list to the left
  @head: the head of the list
 */
static inline void list_rotate_left(ListCore *head)
{
    ListCore *first;

    if (!list_empty(head)) {
        first = head->next;
        list_move_tail(first, head);
    }
}
/*
  list_is_singular - tests whether a list has just one entry.
  @head: the list to test.
 */
static inline int list_is_singular(const ListCore *head)
{
    return !list_empty(head) && (head->next == head->prev);
}

static inline void __list_cut_position(ListCore *list,
        ListCore *head, ListCore *entry)
{
    ListCore *newList_first = entry->next;
    list->next = head->next;
    list->next->prev = list;
    list->prev = entry;
    entry->next = list;
    head->next = newList_first;
    newList_first->prev = head;
}
/*
  list_cut_position - cut a list into two
  @list: a newList list to add all removed entries
  @head: a list with entries
  @entry: an entry within head, could be the head itself
    and if so we won't cut the list

  This helper moves the initial part of @head, up to and
  including @entry, from @head to @list. You should
  pass on @entry an element you know is on @head. @list
  should be an empty list or a list you do not care about
  losing its data.
 *
 */
static inline void list_cut_position(ListCore *list,
        ListCore *head, ListCore *entry)
{
    if (list_empty(head))
        return;
    if (list_is_singular(head) &&
        (head->next != entry && head != entry))
        return;
    if (entry == head)
        INIT_LIST_HEAD(list);
    else
        __list_cut_position(list, head, entry);
}

static inline void __list_splice(const ListCore *list,
                 ListCore *prev,
                 ListCore *next)
{
    ListCore *first = list->next;
    ListCore *last = list->prev;

    first->prev = prev;
    prev->next = first;

    last->next = next;
    next->prev = last;
}

/*
  list_splice - join two lists, this is designed for stacks
  @list: the newList list to add.
  @head: the place to add it in the first list.
 */
static inline void list_splice(const ListCore *list,
                ListCore *head)
{
    if (!list_empty(list))
        __list_splice(list, head, head->next);
}

/*
  list_splice_tail - join two lists, each list being a queue
  @list: the newList list to add.
  @head: the place to add it in the first list.
 */
static inline void list_splice_tail(ListCore *list,
                ListCore *head)
{
    if (!list_empty(list))
        __list_splice(list, head->prev, head);
}

/*
  list_splice_init - join two lists and reinitialise the emptied list.
  @list: the newList list to add.
  @head: the place to add it in the first list.

  The list at @list is reinitialised
 */
static inline void list_splice_init(ListCore *list,
                    ListCore *head)
{
    if (!list_empty(list)) {
        __list_splice(list, head, head->next);
        INIT_LIST_HEAD(list);
    }
}
/*
  list_splice_tail_init - join two lists and reinitialise the emptied list
  @list: the newList list to add.
  @head: the place to add it in the first list.

  Each of the lists is a queue.
  The list at @list is reinitialised
 */
static inline void list_splice_tail_init(ListCore *list,
                     ListCore *head)
{
    if (!list_empty(list)) {
        __list_splice(list, head->prev, head);
        INIT_LIST_HEAD(list);
    }
}
/**********************************************************
获取link节点对应的结构体变量地址
ptr:   链表节点指针
type:   结构体类型名
member: 结构体成员变量名
**********************************************************/
#define list_entry(ptr, type, member) \
    container_of(ptr, type, member)

/**********************************************************
获取链表头节点对应的结构体变量地址
ptr:   链表头指针
type:   结构体类型名
member: 结构体成员变量名
Note:
链表头节点实际为链表头的下一个节点,链表头未使用，相当于哨兵
**********************************************************/
#define list_first_entry(ptr, type, member) \
    list_entry((ptr)->next, type, member)

/**********************************************************
获取链表尾节点对应的结构体变量地址
ptr:   链表头指针
type:   结构体类型名
member: 结构体成员变量名
**********************************************************/
#define list_last_entry(ptr, type, member) \
    list_entry((ptr)->prev, type, member)

/*
list_first_entry_or_null -从列表中获得的第一个元素
@ptr：榜头把元素从。
@type：这是嵌入式的类型。
@member：在结构的list_head名称。
请注意，如果列表为空，则返回null .。
 */
#define list_first_entry_or_null(ptr, type, member) \
    (!list_empty(ptr) ? list_first_entry(ptr, type, member) : NULL)

/*
list_next_entry -获得列表的下一个元素
“@pos：类型*光标
@member：在结构的list_head名称。
 */
#define list_next_entry(pos, member) \
    list_entry((pos)->member.next, typeof(*(pos)), member)

/*
list_prev_entry -列表获得prev元素
@pos：式游标
@member：在结构的list_head名称。
 */
#define list_prev_entry(pos, member) \
    list_entry((pos)->member.prev, typeof(*(pos)), member)

/*
list_for_each -遍历列表
@pos：& listcore作为循环游标。
@head：你的名单的头。
 */
#define list_for_each(pos, head) \
    for (pos = (head)->next; pos != (head); pos = pos->next)

/*
list_for_each_prev -遍历列表向后
@pos ：& listcore作为循环游标。
@head ：你的名单的头。
 */
#define list_for_each_prev(pos, head) \
    for (pos = (head)->prev; pos != (head); pos = pos->prev)

/*
list_for_each_safe -遍历列表和列表项安全去除
@pos ：& listcore作为循环游标。
@n   ：另一个listcore作为临时存储
@head：你的名单的头。
 */
#define list_for_each_safe(pos, n, head) \
    for (pos = (head)->next, n = pos->next; pos != (head); \
        pos = n, n = pos->next)

/*
list_for_each_prev_safe -向后遍历安全对列表条目删除名单
@pos：& listcore作为循环游标。
@ N：另一个listcore作为临时存储
@head：你的名单的头。
 */
#define list_for_each_prev_safe(pos, n, head) \
    for (pos = (head)->prev, n = pos->prev; \
         pos != (head); \
         pos = n, n = pos->prev)

/*
list_for_each_entry -遍历给定类型列表
@pos：类型*作为循环游标。
@head：你的名单的头。
@member：在结构的list_head名称
 */
#define list_for_each_entry(pos, head, member)				\
    for (pos = list_first_entry(head, typeof(*pos), member);	\
         &pos->member != (head);					\
         pos = list_next_entry(pos, member))

/*
list_for_each_entry_reverse -迭代向后在给定类型的列表。
@pos：类型*作为循环游标。
@head：你的名单的头。
@member：在结构的list_head名称。
 */
#define list_for_each_entry_reverse(pos, head, member)			\
    for (pos = list_last_entry(head, typeof(*pos), member);		\
         &pos->member != (head); 					\
         pos = list_prev_entry(pos, member))

/*
list_prepare_entry准备用于list_for_each_entry_continue() POS进入
@pos：类型*使用为出发点
@head：列表的头
@member：在结构的list_head名称。
准备一个用于list_for_each_entry_continue()起点POS进入。
 */
#define list_prepare_entry(pos, head, member) \
    ((pos) ? : list_entry(head, typeof(*pos), member))

/*
list_for_each_entry_continue -继续在给定类型列表迭代
@pos：类型*作为循环游标。
@head：你的名单的头。
@member：在结构的list_head名称。
继续遍历给定类型的列表，当前位置后继续。
 */
#define list_for_each_entry_continue(pos, head, member) 		\
    for (pos = list_next_entry(pos, member);			\
         &pos->member != (head);					\
         pos = list_next_entry(pos, member))

/*
list_for_each_entry_continue_reverse -迭代向后从给定的点
@pos：类型*作为循环游标。
@head：你的名单的头。
@member：在结构的list_head名称。
开始向后遍历给定类型的列表，当前位置后继续。
 */
#define list_for_each_entry_continue_reverse(pos, head, member)		\
    for (pos = list_prev_entry(pos, member);			\
         &pos->member != (head);					\
         pos = list_prev_entry(pos, member))

/*


list_for_each_entry_from -遍历了从目前点式列表
@pos：类型*作为循环游标。
@head：你的名单的头。
@member：在结构的list_head名称。
遍历给定类型的列表，继续从当前位置。
 */
#define list_for_each_entry_from(pos, head, member) 			\
    for (; &pos->member != (head);					\
         pos = list_next_entry(pos, member))

/*
list_for_each_entry_safe -遍历给定类型的安全攻击列表条目删除名单
@pos：类型*作为循环游标。
@N:另一种类型*用作临时存储
@head：你的名单的头。
@member：在结构的list_head名称。
 */
#define list_for_each_entry_safe(pos, n, head, member)			\
    for (pos = list_first_entry(head, typeof(*pos), member),	\
        n = list_next_entry(pos, member);			\
         &pos->member != (head); 					\
         pos = n, n = list_next_entry(n, member))

/*


list_for_each_entry_safe_continue -继续列出迭代对安全的去除
@pos：类型*作为循环游标。
@N:另一种类型*用作临时存储
@head：你的名单的头。
@member：在结构的list_head名称。
遍历给定类型的列表，在目前点位继续，对列表条目删除安全。
 */
#define list_for_each_entry_safe_continue(pos, n, head, member) 		\
    for (pos = list_next_entry(pos, member), 				\
        n = list_next_entry(pos, member);				\
         &pos->member != (head);						\
         pos = n, n = list_next_entry(n, member))

/*
list_for_each_entry_safe_from -遍历列表从当前点对安全的去除

@pos：类型*作为循环游标。
@n :@N:另一种类型*用作临时存储
@head：你的名单的头。
@member：在结构的list_head名称。
遍历了从当前点式列表，在列表条目删除安全。
 */
#define list_for_each_entry_safe_from(pos, n, head, member) 			\
    for (n = list_next_entry(pos, member);					\
         &pos->member != (head);						\
         pos = n, n = list_next_entry(n, member))

/*
list_for_each_entry_safe_reverse -迭代回顾过去的列表对安全的去除
@pos：类型*作为循环游标。
@N:另一种类型*用作临时存储
@head：你的名单的头。
@member：在结构的list_head名称。
迭代回顾过去的给定类型的列表，在列表条目删除安全。
 */
#define list_for_each_entry_safe_reverse(pos, n, head, member)		\
    for (pos = list_last_entry(head, typeof(*pos), member),		\
        n = list_prev_entry(pos, member);			\
         &pos->member != (head); 					\
         pos = n, n = list_prev_entry(n, member))

/*
list_safe_reset_next重置一个陈旧的list_for_each_entry_safe环
@pos：用于list_for_each_entry_safe循环游标
@ N：临时存储用于list_for_each_entry_safe
@member：在结构的list_head名称。
list_safe_reset_next不安全使用，
一般如果列表可能会修改的同时（如锁在环体下降）。
一个例外是如果光标元（POS）被固定在列表中，
并list_safe_reset_next重新以锁完成体内循环的当前迭代前后称。
 */
#define list_safe_reset_next(pos, n, member)				\
    n = list_next_entry(pos, member)

#endif // KERNELLIST_H
